package com.esheeper.CAS.Util;

import com.esheeper.CAS.Pojo.User;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Date;


/**
 * PasswordUtil
 *
 * @author Wenyang Su
 * @version 1.0.0
 * @description 关于密码的处理
 * @date 2023-05-16
 */
@Service
public class CryptUtil {

    /**
     * 方法名
     *
     * @param originalPassword 原始密码串
     * @return 加密后并格式化后的密码串
     * @description 使用MD5不可逆加密，然后采用Base64方式格式化
     * @author Wenyang Su
     * @date 2023-05-16
     * @version 1.0.0
     */
    @Value("${crypt.md5.salt}")
    String salt;
    public String FormatPassword(String originalPassword) throws NoSuchAlgorithmException {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update((originalPassword + salt).getBytes());
        String hashedPwd = new BigInteger(1, md5.digest()).toString(16);
        System.out.println(hashedPwd);
        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(md5.digest());
    }

    public String GenerateToken(User user, Date expires) throws NoSuchAlgorithmException {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update((user.getId() + user.getUsername() + salt + expires.toString()).getBytes());
        String hashedPwd = new BigInteger(1, md5.digest()).toString(16);
        System.out.println(hashedPwd);
        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(md5.digest());
    }

    public final int VERY_WEAK= 0;
    public final int WEAK= 1;
    public final int AVERAGE= 2;
    public final int STRONG= 3;
    public final int VERY_STRONG= 4;
    public final int SECURE= 5;
    public final int VERY_SECURE= 6;

    public int GetPwdSecurityLevel(String pPasswordStr) {
        int safelevel = VERY_WEAK;
        if (pPasswordStr == null) {
            return safelevel;
        }
        int grade = 0;
        int index = 0;
        char[] pPsdChars = pPasswordStr.toCharArray();

        int numIndex = 0;
        int sLetterIndex = 0;
        int lLetterIndex = 0;
        int symbolIndex = 0;

        for (char pPsdChar : pPsdChars) {
            int ascll = pPsdChar;
            if (ascll >= 48 && ascll <= 57) {
                numIndex++;
            } else if (ascll >= 65 && ascll <= 90) {
                lLetterIndex++;
            } else if (ascll >= 97 && ascll <= 122) {
                sLetterIndex++;
            } else if ((ascll >= 33 && ascll <= 47)
                    || (ascll >= 58 && ascll <= 64)
                    || (ascll >= 91 && ascll <= 96)
                    || (ascll >= 123 && ascll <= 126)) {
                symbolIndex++;
            }
        }
        /*
         * 一、密码长度: 5 分: 小于等于 4 个字符 10 分: 5 到 7 字符 25 分: 大于等于 8 个字符
         */
        if (pPsdChars.length <= 4) {
            index = 5;
        } else if (pPsdChars.length <= 7) {
            index = 10;
        } else {
            index = 25;
        }
        grade += index;

        /*
         * 二、字母: 0 分: 没有字母 10 分: 全都是小（大）写字母 20 分: 大小写混合字母
         */
        if (lLetterIndex == 0 && sLetterIndex == 0) {
            index = 0;
        } else if (lLetterIndex != 0 && sLetterIndex != 0) {
            index = 20;
        } else {
            index = 10;
        }
        grade += index;
        /*
         * 三、数字: 0 分: 没有数字 10 分: 1 个数字 20 分: 大于 1 个数字
         */
        if (numIndex == 0) {
            index = 0;
        } else if (numIndex == 1) {
            index = 10;
        } else {
            index = 20;
        }
        grade += index;

        /*
         * 四、符号: 0 分: 没有符号 10 分: 1 个符号 25 分: 大于 1 个符号
         */
        if (symbolIndex == 0) {
            index = 0;
        } else if (symbolIndex == 1) {
            index = 10;
        } else {
            index = 25;
        }
        grade += index;
        /*
         * 五、奖励: 2 分: 字母和数字 3 分: 字母、数字和符号 5 分: 大小写字母、数字和符号
         */
        if ((sLetterIndex != 0 || lLetterIndex != 0) && numIndex != 0) {
            index = 2;
        } else if ((sLetterIndex != 0 || lLetterIndex != 0) && numIndex != 0
                && symbolIndex != 0) {
            index = 3;
        } else if (sLetterIndex != 0 && lLetterIndex != 0 && numIndex != 0
                && symbolIndex != 0) {
            index = 5;
        }
        grade += index;

        /*
         * 最后的评分标准: >= 90: 非常安全 >= 80: 安全（Secure） >= 70: 非常强 >= 60: 强（Strong） >=
         * 50: 一般（Average） >= 25: 弱（Weak） >= 0: 非常弱
         */
        if(grade >=90){
            safelevel = VERY_SECURE;
        }else if(grade >= 80){
            safelevel = SECURE;
        }else if(grade >= 70){
            safelevel = VERY_STRONG;
        }else if(grade >= 60){
            safelevel = STRONG;
        }else if(grade >= 50){
            safelevel = AVERAGE;
        }else if(grade >= 25){
            safelevel = WEAK;
        }else if(grade >= 0){
            safelevel = VERY_WEAK;
        }
        return safelevel;
    }
}
